package baseserverframe;

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

//------------------------------------------------------------------------------
import java.util.Vector;
import javax.swing.UIManager;
import javax.swing.SwingUtilities;





/*******************************************************************************
 *
 * Frame class.
 *
 * It organizes specified documents, witch can contain different views and
 * hotbars. This class extends JFrame.
 *
 * @author Truewar Ashman (<a href="mailto:truewar@hotmail.ru">truewar@hotmail.ru</a>) ID = 2009
 * @version 0.3<br>
 * @see document
 * @see view
 */
public class mainFrame extends JFrame
{
	private Vector <document> docs;
	private int currentDoc;
//+Look And Feels
	private UIManager.LookAndFeelInfo[] LE;	// Набор шкурок.
	private int numberOfSkins;				// Количество загруженных шкурок.
//-Look And Feels
	final JMenuBar newMenu	= new JMenuBar();
	final JMenu docMenu		= new JMenu("Представления");
	final JMenu helpMenu	= new JMenu("Помощь");

	/**
	 * Class constructor<br>
	 */
	public mainFrame()
	{
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		docs = new Vector <document>();
	}

	/**
	 * Initialization of components.
	 * 
	 * It creates component managers, event links and menu to change
	 * different elements, such as current view and document. It also 
	 * organizes hot bars and status bars in frame.
	 * 
	 */
	public void init()
	{
		GridBagLayout gbl;
		GridBagConstraints c;
		gbl = new GridBagLayout();
		c =  new GridBagConstraints();
		JToolBar hotBars = new JToolBar();
		JPanel mainPanel = new JPanel();
		JPanel statPanel = new JPanel();

		if((currentDoc == -1)||(docs.get(currentDoc).getCurrentView() == null))
		{
			System.out.println("Ошибка инициализации. Нет представления или документа.");
			paintAll(getGraphics());
			SwingUtilities.updateComponentTreeUI(this);
			return;
		}

		for(int i = 0; i < docs.size(); i++)
		{
			final int t1 = i;
			JMenu doc = new JMenu(docs.get(i).getDocName());
			for(int j = 0; j < docs.get(t1).getNumOfView(); j++)
			{
				final int t2 = j;
				JMenuItem it = new JMenuItem(docs.get(t1).getView(j).getViewName());
				it.addActionListener(new ActionListener()
				{
					@Override
					public void actionPerformed(java.awt.event.ActionEvent e)
					{
						clear();
						setCurrentDoc(docs.get(t1).getDocName());
						docs.get(t1).setCurrentView(docs.get(t1).getView(t2).getViewName());
						init();
					}

				});
				doc.add(it);
			}
			docMenu.add(doc);
		}

		newMenu.add(docMenu);
		if(docs.get(currentDoc).getCurrentView().getMenu() != null)
		{
			for(int i = 0; i <  docs.get(currentDoc).getCurrentView().getMenu().getSubElements().length; i++)
			{
				newMenu.add(docs.get(currentDoc).getCurrentView().getMenu().getSubElements()[i].getComponent());
			}
		}
		newMenu.add(helpMenu);
		
	
// +menu
		setJMenuBar(newMenu);
// -menu
// +hot bars
		c.anchor = GridBagConstraints.WEST;
		c.fill   = GridBagConstraints.NONE;
		c.gridwidth = 1;
		c.gridheight = 1;
		c.gridx = 0;
		c.gridy = 0;
		c.ipadx = 0;
		c.ipady = 0;
		c.weightx = GridBagConstraints.REMAINDER;
		c.weighty = 1;
		c.insets = new Insets(5, 15, 0, 2);

		int numOfHB = docs.get(currentDoc).getCurrentView().getNumOfHB();
		for(int i = 0; i < numOfHB; i++)
		{
			Component hb = docs.get(currentDoc).getCurrentView().getHotBar(i);
			gbl.setConstraints(hb, c);
			hotBars.add(hb);
			c.gridx = i;
		}

		Component view = docs.get(currentDoc).getCurrentView().getView();
		c.fill  = GridBagConstraints.BOTH;
		c.gridx = 0;
		c.gridy = 0;
		c.weightx = 1;
		c.insets = new Insets(5, 5, 5, 5);

		gbl.setConstraints(view, c);
		if(view != null)
			mainPanel.add(view);
				
		mainPanel.setLayout(gbl);

		int numOfStat = docs.get(currentDoc).getNumOfStat();
		c.fill  = GridBagConstraints.HORIZONTAL;
		for(int i = 0; i < numOfStat; i++)
		{
			c.gridy = i*2;
			Component stat = docs.get(currentDoc).getStatus(i);
			gbl.setConstraints(stat, c);
			statPanel.add(stat);

			if(i != numOfStat-1)
			{
				JSeparator sep = new JSeparator();
				c.gridy = i*2+1;
				gbl.setConstraints(sep, c);
				statPanel.add(sep);
			}
		}
		statPanel.setLayout(gbl);

		add(hotBars, BorderLayout.NORTH);
		add(mainPanel, BorderLayout.CENTER);
		add(statPanel, BorderLayout.SOUTH);
		paintAll(getGraphics());
		SwingUtilities.updateComponentTreeUI(this);

	}

	/**
	 * Frame cleaner.
	 * 
	 * It makes frame free from all components.
	 */
	public void clear()
	{
		this.removeAll();
		if((currentDoc == -1)||(docs.get(currentDoc).getCurrentView() == null)) return;
		newMenu.remove(docMenu);
		docMenu.removeAll();
		newMenu.remove(helpMenu);
		helpMenu.removeAll();
		if(docs.get(currentDoc).getCurrentView().getMenu() != null)
		{
			for(int i = 0; i < newMenu.getSubElements().length; i++)
			{
				docs.get(currentDoc).getCurrentView().getMenu().add(newMenu.getSubElements()[i].getComponent());
			}
		}	
		newMenu.removeAll();
		this.frameInit();
	}

	/**
	 * Method to add document into frame.
	 * 
	 * @param name - logical name of document
	 * @param newDoc - link to document.
	 * @return <br>&nbsp;&nbsp;&nbsp;&nbsp;<b>true</b> - document was successfully added.
	 *		   <br>&nbsp;&nbsp;&nbsp;&nbsp;<b>false</b> - document with that name was already registered.
	 */
	public boolean addDoc(String name, document newDoc)
	{
		int cur = getDocByName(name);
		if(cur != -1) return false;

		newDoc.setDocName(name);
		docs.add(newDoc);
		newDoc.setFrameLink(this);
		return true;
	}

// +Methods by name ------------------------------------------------------------
	/**
	 * Method to remove document by name.
	 *
	 * @param name - logical name of document.
	 * @return <br>&nbsp;&nbsp;&nbsp;&nbsp;<b>true</b> - document was successfully removed.
	 *		   <br>&nbsp;&nbsp;&nbsp;&nbsp;<b>false</b> - there are no document with such name.
	 */
	public boolean removeDoc(String name)
	{
		int rem = getDocByName(name);
		if(rem == -1) return false;

		docs.remove(rem);
		currentDoc = -1;
		return true;
	}

	/**
	 * Method to set current document by name.
	 *
	 * @param name - logical name of document.
	 * @return <br>&nbsp;&nbsp;&nbsp;&nbsp;<b>true</b> - document was successfully set.
	 *		   <br>&nbsp;&nbsp;&nbsp;&nbsp;<b>false</b> - there are no document with such name.
	 */
	public boolean setCurrentDoc(String name)
	{
		int cur = getDocByName(name);
		if(cur == -1) return false;

		currentDoc = cur;
		return true;
	}

// -Methods by name ------------------------------------------------------------
// +Methods by index -----------------------------------------------------------

	/**
	 * Method to remove document by index.
	 *
	 * @param id - index of document.
	 * @return <br>&nbsp;&nbsp;&nbsp;&nbsp;<b>true</b> - document was successfully removed.
	 *		   <br>&nbsp;&nbsp;&nbsp;&nbsp;<b>false</b> - there are no document with such index.
	 */
	public boolean removeDoc(int id)
	{
		if((id < 0)||(id > docs.size()))
			return false;
		docs.remove(id);
		return true;
	}
	/**
	 * Method to set current document by index.
	 *
	 * @param id - index of document.
	 * @return <br>&nbsp;&nbsp;&nbsp;&nbsp;<b>true</b> - document was successfully set.
	 *		   <br>&nbsp;&nbsp;&nbsp;&nbsp;<b>false</b> - there are no document with such index.
	 */
	public boolean setCurrentDoc(int id)
	{
		if((id < 0)||(id > docs.size()))
			return false;
		currentDoc = id;
		return true;
	}
// -Methods by index -----------------------------------------------------------
/**
 *  Loading of L&F.<br>
 *
 *	@return number of L&F.
 */
	public int getAllSkins()
	{
		LE = UIManager.getInstalledLookAndFeels();
		int cnt = 0;
		for (UIManager.LookAndFeelInfo info : LE)
			cnt++;
		return cnt;
	}

/**
 *  Setting L&F by index <br>
 *
 */
	public void setSkin()
	{
		try
		{
			UIManager.setLookAndFeel( new com.nilo.plaf.nimrod.NimRODLookAndFeel());
			SwingUtilities.updateComponentTreeUI(this);
		}catch(Exception e) {e.printStackTrace();}
	}

/**
 *  Method to get name of L&F by index.<br>
 *
 *	@param t index of L&F.
 *  @return name of L&F.
 */
	public String getSkinName(int t)
	{
		if((t >= 0)||(t < numberOfSkins))
			return LE[t].getName();
		else return "No class";

	}	
// +private---------------------------------------------------------------------

/**
 *  Method to get index of document by name.<br>
 *
 * @param name logical name of document.
 * @return <br>&nbsp;&nbsp;&nbsp;&nbsp;<b>int</b> - index of specified document.
 */
	private int getDocByName(String name)
	{
		for(int i = 0; i < docs.size(); i++)
		{
			if(docs.get(i).getDocName().compareTo(name) == 0)
				return i;
		}
		return -1;
	}
// -private---------------------------------------------------------------------
}
